// Copyright (c) 2021 Presto Labs Pte. Ltd.
// Author: chensili

#include "coin2/exchange/binance/order_v1/parser.h"

#include <memory>

#include "coin2/exchange/base/market/market_exchange_api.h"
#include "coin2/exchange/binance_futures/order_v1/parser.h"
#include "coin2/exchange/bitbank/order_v1/parser.h"
#include "coin2/exchange/bitflyer_futures/order_v1/parser.h"
#include "coin2/exchange/bithumb/order_v2/parser.h"
#include "coin2/exchange/bitmex/order_v1/parser.h"
#include "coin2/exchange/bitstamp/order_v2/parser.h"
#include "coin2/exchange/bybit_futures/order_v2/parser.h"
#include "coin2/exchange/coinone/order_v2/parser.h"
#include "coin2/exchange/factory/order/parser.h"
#include "coin2/exchange/ftx/order_v1/parser.h"
#include "coin2/exchange/ftx_futures/order_v1/parser.h"
#include "coin2/exchange/gateio/order_v4/parser.h"
#include "coin2/exchange/gateio_futures/order_v4/parser.h"
#include "coin2/exchange/gdax/order_v1/parser.h"
#include "coin2/exchange/gopax/order_v1/parser.h"
#include "coin2/exchange/huobi/order_v1/parser.h"
#include "coin2/exchange/huobi_futures/order_v1/parser.h"
#include "coin2/exchange/korbit/order_v1/parser.h"
#include "coin2/exchange/kraken/order_v1/parser.h"
#include "coin2/exchange/lmax_digital/order_v1/parser.h"
#include "coin2/exchange/okex/order_v3/parser.h"
#include "coin2/exchange/okex_futures/order_v3/parser.h"
#include "coin2/exchange/okex_v5/order_v5/parser.h"
#include "coin2/exchange/okex_v5_futures/order_v5/parser.h"
#include "coin2/exchange/prex_futures/order_v1/parser.h"
#include "coin2/exchange/upbit/order_v1/parser.h"
#include "coin2/exchange/mercado/order_v4/parser.h"

namespace coin2::exchange::factory::order {
std::unique_ptr<coin2::exchange::base::order::BaseParser> CreateOrderParser(
    const MarketExchangeApi& mea) {
  if (mea == MarketExchangeApi{MarketType::Spot, ExchangeType::Binance, "v1"}) {
    return std::make_unique<binance::order_v1::BinanceParser>();
  } else if (
      mea == MarketExchangeApi{MarketType::Futures, ExchangeType::Binance, "v1"} ||
      mea == MarketExchangeApi{MarketType::Futures, ExchangeType::Binance, "v1-delivery"}) {
    return std::make_unique<binance_futures::order_v1::BinanceFuturesParser>();
  } else if (mea == MarketExchangeApi{MarketType::Spot, ExchangeType::Bitbank, "v1"}) {
    return std::make_unique<bitbank::order_v1::BitbankParser>();
  } else if (
      mea == MarketExchangeApi{MarketType::Futures, ExchangeType::Bitflyer, "v1"} ||
      mea == MarketExchangeApi{MarketType::Spot, ExchangeType::Bitflyer, "v1"}) {
    return std::make_unique<bitflyer_futures::order_v1::BitflyerFuturesParser>();
  } else if (mea == MarketExchangeApi{MarketType::Spot, ExchangeType::Bithumb, "v2"}) {
    return std::make_unique<bithumb::order_v2::BithumbParser>();
  } else if (mea == MarketExchangeApi{MarketType::Futures, ExchangeType::Bitmex, "v1"}) {
    return std::make_unique<bitmex::order_v1::BitmexParser>();
  } else if (mea == MarketExchangeApi{MarketType::Spot, ExchangeType::Bitstamp, "v2"}) {
    return std::make_unique<bitstamp::order_v2::BitstampParser>();
  } else if (
      mea == MarketExchangeApi{MarketType::Futures, ExchangeType::Bybit, "v2"} ||
      mea == MarketExchangeApi{MarketType::Futures, ExchangeType::Bybit, "v2-linear"}) {
    return std::make_unique<bybit_futures::order_v2::BybitFuturesParser>();
  } else if (mea == MarketExchangeApi{MarketType::Spot, ExchangeType::Coinone, "v2"}) {
    return std::make_unique<coinone::order_v2::CoinoneParser>();
  } else if (mea == MarketExchangeApi{MarketType::Futures, ExchangeType::Ftx, "v1"}) {
    return std::make_unique<ftx_futures::order_v1::FtxFuturesParser>();
  } else if (mea == MarketExchangeApi{MarketType::Spot, ExchangeType::Gopax, "v1"}) {
    return std::make_unique<gopax::order_v1::GopaxParser>();
  } else if (
      mea == MarketExchangeApi{MarketType::Futures, ExchangeType::Huobi, "v1"} ||
      mea == MarketExchangeApi{MarketType::Futures, ExchangeType::Huobi, "v1-swap"} ||
      mea == MarketExchangeApi{MarketType::Futures, ExchangeType::Huobi, "v1-linear-swap"}) {
    return std::make_unique<huobi_futures::order_v1::HuobiFuturesParser>();
  } else if (mea == MarketExchangeApi{MarketType::Spot, ExchangeType::Huobi, "v1"}) {
    return std::make_unique<huobi::order_v1::HuobiParser>();
  } else if (mea == MarketExchangeApi{MarketType::Spot, ExchangeType::Korbit, "v1"}) {
    return std::make_unique<korbit::order_v1::KorbitParser>();
  } else if (mea == MarketExchangeApi{MarketType::Spot, ExchangeType::Korbit, "v1"}) {
    return std::make_unique<korbit::order_v1::KorbitParser>();
  } else if (mea == MarketExchangeApi{MarketType::Spot, ExchangeType::Lmaxdigital, "v1"}) {
    return std::make_unique<lmax_digital::order_v1::LmaxdigitalParser>();
  } else if (
      mea == MarketExchangeApi{MarketType::Futures, ExchangeType::Okex, "v3"} ||
      mea == MarketExchangeApi{MarketType::Futures, ExchangeType::Okex, "v3-swap"}) {
    return std::make_unique<okex_futures::order_v3::OkexFuturesParser>();
  } else if (mea == MarketExchangeApi{MarketType::Spot, ExchangeType::Okex, "v3"}) {
    return std::make_unique<okex::order_v3::OkexParser>();
  } else if (
      mea == MarketExchangeApi{MarketType::Futures, ExchangeType::Okex, "v5"} ||
      mea == MarketExchangeApi{MarketType::Futures, ExchangeType::Okex, "v5-swap"}) {
    return std::make_unique<okex_v5_futures::order_v5::OkexV5FuturesParser>();
  } else if (mea == MarketExchangeApi{MarketType::Spot, ExchangeType::Okex, "v5"}) {
    return std::make_unique<okex_v5::order_v5::OkexV5Parser>();
  } else if (mea == MarketExchangeApi{MarketType::Futures, ExchangeType::Prex, "v1"}) {
    return std::make_unique<prex_futures::order_v1::PrexFuturesParser>();
  } else if (mea == MarketExchangeApi{MarketType::Spot, ExchangeType::Upbit, "v1"}) {
    return std::make_unique<upbit::order_v1::UpbitParser>();
  } else if (mea == MarketExchangeApi{MarketType::Spot, ExchangeType::Kraken, "v1"}) {
    return std::make_unique<kraken::order_v1::KrakenParser>();
  } else if (mea == MarketExchangeApi{MarketType::Spot, ExchangeType::Gateio, "v4"}) {
    return std::make_unique<gateio::order_v4::GateioParser>();
  } else if (
      mea == MarketExchangeApi{MarketType::Futures, ExchangeType::Gateio, "v4"} ||
      mea == MarketExchangeApi{MarketType::Futures, ExchangeType::Gateio, "v4-delivery"}) {
    return std::make_unique<gateio_futures::order_v4::GateioFuturesParser>();
  } else if (mea == MarketExchangeApi{MarketType::Spot, ExchangeType::Mercado, "v4"}) {
    return std::make_unique<mercado::order_v4::MercadoParser>();
  } else {
    THROW() << "[Parser Factory] unknown mea: " << mea.String();
  }
  return {};
}
}  // namespace coin2::exchange::factory::order
